package kpi.java_training.domain.teaching;

import kpi.java_training.domain.Model;
import kpi.java_training.domain.questions.QuestionData;
import kpi.java_training.domain.questions.Topic;
import kpi.java_training.utils.DomDataSaver;
import kpi.java_training.utils.Log;
import kpi.java_training.utils.StaxDataLoader;
import kpi.java_training.utils.UserSavedData;

import java.util.*;

/**
 * Created by Alex Kebkalo on 13.11.13.
 * class implements teaching process
 */
public class TeachingSystem implements Model {
    private List<Teacher> teachers;
    private Queue<Teacher> queue;
    private List<Topic> originalQuestions;
    private AnswersList answers;
    private UserSavedData userSavedData;

    private Teacher currentTeacher;

    public boolean getResult() {
        return previousResult;
    }

    private boolean previousResult;

    public TeachingSystem(String user) {
        teachers = new ArrayList<>();
        originalQuestions = null;
        queue = new LinkedList<>();
        answers = null;
        userSavedData = new UserSavedData(user);
    }

    private void addStandardQuestions() {
        for (Teacher teacher : teachers) {
            queue.add(teacher);
        }
    }

    public void setNextStep() {
        if (workComplete()) {
            return;
        }
        if (queue.isEmpty()) {
            addStandardQuestions();
        }
        currentTeacher = queue.peek();
    }

    public void processAnswer(String answer) {
        processQueue(answer);
        answers.add(answer);
    }

    private void processQueue(String answer) {
        queue.poll();
        previousResult = currentTeacher.parseUserAnswer(answer);
        if (previousResult) {
            checkDone(currentTeacher);
        } else {
            queue.add(currentTeacher);
        }
    }

    public QuestionData getCurrentQuestionData() {
        return currentTeacher.getQuestionData();
    }

    public boolean workComplete() {
        return teachers.isEmpty();
    }

    public boolean savedSessionExists() {
        return userSavedData.savedDataExists();
    }

    public void startNewSession() {
        StaxDataLoader loader = new StaxDataLoader(userSavedData.getDefaultFileName());
        try {
            originalQuestions = loader.loadQuestions();
        } catch (Exception e) {
            Log.writeToLog(e);
        }
        answers = new AnswersList();
        for (Topic topic : originalQuestions) {
            topic.shuffle();
        }
        loadTeachers();
    }

    public void continueSavedSession() {
        if (!userSavedData.savedDataExists()) {
            startNewSession();
            return;
        }
        StaxDataLoader loader = new StaxDataLoader(userSavedData.getUserFileName());
        try {
            originalQuestions = loader.loadQuestions();
            answers = new AnswersList(loader.loadAnswers());
        } catch (Exception e) {
            Log.writeToLog(e);
        }
        loadTeachers();
        processExistingAnswers();
    }

    private void loadTeachers() {
        teachers.clear();
        queue.clear();
        for (Topic topic : originalQuestions) {
            teachers.add(new Teacher(topic.getTeachingList(), topic.getTopicName()));
        }
    }

    private void checkDone(Teacher teacher) {
        if (teacher.teachingDone()) {
            teachers.remove(teacher);
        }
    }

    public void executeBreak() {
        teachers.clear();
        try {
            DomDataSaver saver = new DomDataSaver(userSavedData.getUserFileName());
            saver.saveTeachingData(originalQuestions, answers.getAnswers());
        } catch (Exception e) {
            Log.writeToLog(e);
        }
    }

    public void executeUndo() {
        if (answers.isEmpty()) {
            return;
        }
        answers.removeLastAnswer();
        answers.resetAnswersCounter();
        loadTeachers();
        processExistingAnswers();
    }

    private void processExistingAnswers() {
        for (int i=0; i < answers.size(); i++) {
            setNextStep();
            processQueue(answers.getNextAnswer());
        }
    }
}
